This tutorial is an introduction to using Leaflet through R to make dynamic and interactive maps.
R is a great tool for map making for a few reasons: first, there are many pre-existing map making libraries in R, and more are being added all the time. Second, R is very popular and free, open-source software, which makes it a fairly accessible option for mapping projects. Finally, making maps using programming is a nice way to produce maps that are transparent and accessible - you can share your code with any collaborator, and they will be able to follow the work that you did step-by-step.
Load in the leaflet package and other required packages:
library(leaflet)
library(sf)
## Linking to GEOS 3.11.2, GDAL 3.6.2, PROJ 9.2.0; sf_use_s2() is TRUE
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(ggplot2)
Let’s ‘read-in’ some data into our notebook by assigning values to a variable named ‘south’ (often called ‘reading-in’ data).
south <- st_read("south.shp")
## Reading layer `south' from data source
## `D:\Projects\r-leaflet\spatial_humanities\south\south.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 1412 features and 69 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -106.6495 ymin: 24.95597 xmax: -75.046 ymax: 40.63714
## Geodetic CRS: WGS 84
Now that the data is read-in, let’s have a look by plotting it:
plot(south)
## Warning: plotting the first 9 out of 69 attributes; use max.plot = 69 to plot
## all
## Make Leaflet Plot
Start by calling the leaflet() function and build on your map from there. The ‘%>%’ (sometimes called the pipe operator) tells R to move on to include the next line of code in the map. Add a polygon layer using addPolygons and color it green.
leaflet() %>%
leaflet::addPolygons(data = south, color = "blue", weight = 1, fill = FALSE)
So, now we have a beginning plot. We can make this much more interesting! Let’s add some variables and make them interactive.
Generate a color palette with five values. (Read more about leaflet colors)[https://rstudio.github.io/leaflet/colors.html]
pal_fun <- colorNumeric("YlOrRd", NULL, n = 5)
leaflet() %>%
leaflet::addPolygons(data = south,
# remove polygon borders
stroke = FALSE,
# set fill color with function from above and value
#tell R to use the color palette we created based on the population 1960 variable
fillColor = ~pal_fun(PO60),
#these next two lines change the opacity of the layer and smooth out the polygons a bit - you can keep these settings or play around with them if you want to. Both range between 0 and 1
fillOpacity = 0.8,
smoothFactor = 0.5)
Let’s make it more interactive by adding some pop-up text!
Generate text for the map pop-up:
p_popup <- paste0("Name: ","<strong>",south$NAME,"</strong></br>","State: ","<strong>",south$STATE_NAME,"</strong></br>","<strong>Population 1960: </strong>", south$PO60)
#now plot it with these custom options
leaflet() %>%
leaflet::addPolygons(data = south,
# remove polygon borders
stroke = FALSE,
# set fill color with function from above and value
fillColor = ~pal_fun(PO60),
fillOpacity = 0.8,
smoothFactor = 0.5,
# add pop-up text
popup = p_popup)
leaflet() %>%
leaflet::addPolygons(data = south,
stroke = FALSE,
fillColor = ~pal_fun(PO60),
fillOpacity = 0.8,
smoothFactor = 0.5,
popup = p_popup) %>%
#Use a %>% to tell R to include the next line of code in the map
addLegend("bottomright", # location of legend
pal=pal_fun, # palette function - tells R what colors to include in the legend
values=south$PO60, #Tells R what variable to base the legend on
title = 'Population 1960') # legend title
Next, let’s add a basemap.
leaflet() %>%
leaflet::addPolygons(data = south,
stroke = FALSE,
fillColor = ~pal_fun(PO60),
fillOpacity = 0.8,
smoothFactor = 0.5,
popup = p_popup) %>%
addLegend("bottomright", # location
pal=pal_fun, # palette function
values=south$PO60,
title = 'Population') %>%
#we can do this with one line of code:
addTiles()
We can add different base maps, but these will be third party options so we need a different function to do this. Here’s an example:
leaflet() %>%
leaflet::addPolygons(data = south,
stroke = FALSE,
fillColor = ~pal_fun(PO60),
fillOpacity = 0.8,
smoothFactor = 0.5,
popup = p_popup) %>%
addLegend("bottomright", # location
pal=pal_fun, # palette function
values=south$PO60,
title = 'Population') %>%
#we can do this with one line of code:
addProviderTiles(providers$CartoDB.Positron)
The nice part about leaflet is that we can map more than one variable at a time. We cannot, however, map them both simultaneously: instead, we will have to map them as two separate layers.
#Let's add more than one layer!
#Create palette and pop-up for second layer
p_popup2 <- paste0("<strong>Population 1980: </strong>", south$PO80)
pal_fun2 <- colorNumeric("Blues", NULL, n = 5)
leaflet() %>%
#Add the first layer (variable) to the map
leaflet::addPolygons(data = south,
stroke = FALSE,
fillColor = ~pal_fun(PO60),
fillOpacity = 1,
smoothFactor = 0.5,
popup = p_popup,
group = "1960") %>%
#Next, add the second layer (variable) to the map
leaflet::addPolygons(data = south,
stroke = FALSE,
fillColor = ~pal_fun2(PO80),
fillOpacity = 1,
smoothFactor = 0.5,
popup = p_popup2,
group = "1980") %>%
#Let's add a legend for both of the layers
addLegend("bottomright",
pal=pal_fun,
values=south$PO60,
title = 'Population 1960',
group = "1960") %>%
#Add second legend layer
addLegend("bottomright",
pal=pal_fun2,
values=south$PO80,
title = 'Population 1980',
group = "1980") %>%
#Add base map
addProviderTiles(providers$CartoDB.Positron)
But wait, how do I see the second layer? We have to add one more piece of code:
leaflet() %>%
#Add the first layer (variable) to the map
leaflet::addPolygons(data = south,
stroke = FALSE,
fillColor = ~pal_fun(PO60),
fillOpacity = 1,
smoothFactor = 0.5,
popup = p_popup,
group = "1960") %>%
#Next, add the second layer (variable) to the map
leaflet::addPolygons(data = south,
stroke = FALSE,
fillColor = ~pal_fun2(PO80),
fillOpacity = 1,
smoothFactor = 0.5,
popup = p_popup2,
group = "1980") %>%
#Let's add a legend for both of the layers
addLegend("bottomright",
pal=pal_fun,
values=south$PO60,
title = 'Population 1960',
group = "1960") %>%
#Add second legend layer
addLegend("bottomright",
pal=pal_fun2,
values=south$PO80,
title = 'Population 1980',
group = "1980") %>%
#Add base map
addProviderTiles(providers$CartoDB.Positron)%>%
#This lets us toggle the layers on and off
addLayersControl(overlayGroups = c("1960", "1980"),
options = layersControlOptions(collapsed = FALSE))
What if I want to visualize one variable using points? This is fairly easy to do in R! We will first need to add points, since the data we are currently working with is polygon data. I don’t have point data for this region, so I will create it - I will generate points that fit in the center of each county. This type of point is known as a centroid.
## Warning: st_centroid assumes attributes are constant over geometries
Many thanks to Melissa Haller from Digital and Data Studies
Engel, C. A. (2019). Using Spatial Data with R
R Studio (2016). Leaflet for R